mod gg_2018;
pub mod mta;

use axum::{routing::post, Json, Router};
use axum::extract::State;
use serde::{Deserialize, Serialize};
use std::{net::SocketAddr, sync::Arc};
use curv::elliptic::curves::{secp256_k1::Secp256k1, Scalar};
use anyhow::Result;
use std::fs;
use tokio::sync::Mutex;
use std::sync::mpsc;
use hex;

// 请求参数
#[derive(Deserialize)]
struct SignRequest {
    signStr: String,
}

// 返回值
#[derive(Serialize)]
struct SignResponse {
    code: u16,
    msg: String,
    r: String,
    s: String,
}

async fn sign_handler(Json(payload): Json<SignRequest>) -> Json<SignResponse> {
    match sign(&payload.signStr).await {
        Ok((r, s)) => {
            Json(SignResponse {
                code: 200,
                msg: "签名成功".to_string(),
                r: hex::encode(r.to_bytes().as_ref()),
                s: hex::encode(s.to_bytes().as_ref()),
            })
        }
        Err(e) => {
            Json(SignResponse {
                code: 500,
                msg: format!("签名失败: {}", e),
                r: "".to_string(),
                s: "".to_string(),
            })
        }
    }
}


pub async fn sign(message: &str) -> Result<(Scalar<Secp256k1>, Scalar<Secp256k1>)> {
    fs::create_dir_all("./shared").expect("无法创建共享目录");
    let (tx, rx) = mpsc::channel();
    let (tx2, rx2) = mpsc::channel();

    let handle1 = tokio::spawn({
        let message = message.to_string(); // 传递给 async 闭包
        async move {
            let (r,s) =gg_2018::test::test1(0, 1, &message).await.unwrap();
            tx.send(r).unwrap();
            tx2.send(s).unwrap();
        }
    });

    let handle2 = tokio::spawn({
        let message = message.to_string();
        async move {
            gg_2018::test::test1(1, 0, &message).await.unwrap();
        }
    });

    handle1.await?;
    handle2.await?;

    let r = rx.recv().unwrap();
    let s = rx2.recv().unwrap();

    Ok((r,s))
}

// #[tokio::main]
// async fn main()-> Result<()> {
//     let message = "test";
//     let (r,s) =sign(message).await?;
//     println!("output:r{:?},s{:?}",r,s);
//     Ok(())
//
// }


#[tokio::main]
async fn main() -> Result<()> {

    let app = Router::new().route("/sign", post(sign_handler));

    let addr = SocketAddr::from(([0, 0, 0, 0], 18080));
    println!("Rust签名服务启动于 http://{}", addr);

    let listener = tokio::net::TcpListener::bind(addr).await?;
    axum::serve(listener, app.into_make_service()).await?;

    Ok(())
}


